﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CarbonExchange.AmeeQuery;
using CarbonExchange.Dal;

namespace CarbonExchange.Bll
{
    public class CountryFactory : FactoryBase<Country>
    {
        public CountryFactory() : base() { }

        public CountryFactory(IAmeeCommand ameeCommand) : base(ameeCommand) { }

        public CountryFactory(Context dalContext) : base(dalContext) { }

        public CountryFactory(IAmeeCommand ameeCommand, Context dalContext) : base(ameeCommand, dalContext) { }


        protected override void MarkItemForDeletion(Country item)
        {
            Dal.Country dataItem = item.Convert(base.DalContext);
            if (dataItem != null)
            {
                dataItem.Deleted = true;
            }
        }

        protected override void PopulateDataChanges(Country item, object dataItem)
        {
            Dal.Country tmp = dataItem as Dal.Country;
            if (item.Id == 0)
            {
                item.Id = tmp.Id;
                item.Created = tmp.Created.ToLocalTime();
            }
        }

        protected override object GetDataItemForUpdate(Country item)
        {
            return item.Convert(base.DalContext);
        }

        private IQueryable<Dal.Country> GetSelection()
        {
            var tmp = base.DalContext.Countries.Where(x=>!x.Deleted);
            return tmp;
        }

        public IQueryable<Country> GetAllBySiteId(int siteId)
        {
            return GetSelection().Where(x => x.SiteId == siteId).Convert();
        }

        public Country GetById(int id)
        {
            return GetSelection().Where(x => x.Id == id).SingleOrDefault().Convert();
        }

        protected override void Validate(IQueryable<Country> items, CarbonExchange.Bll.Exceptions.ValidationException exp)
        {
            items.Validate(exp, base.DalContext);
        }

        public Country Insert(int siteId, string locale)
        {
            var tmp = new Country();
            tmp.SiteId = siteId;
            tmp.Locale = locale;
            base.Save(tmp);
            return tmp;
        }
    }

    public static class CountryFactoryConverter
    {
        internal static IQueryable<Country> Convert(this IQueryable<Dal.Country> source)
        {
            return source.Select(x => ConvertItem(x));
        }

        internal static Country Convert(this Dal.Country source)
        {
            return ConvertItem(source);
        }

        internal static Country ConvertItem(Dal.Country item)
        {
            if (item != null)
            {
                return new Country()
                {
                    Id = item.Id,
                    SiteId = item.SiteId,
                    Locale = item.Locale,
                    Conversion = item.Conversion,
                    Created = DateTime.SpecifyKind(item.Created, DateTimeKind.Utc).ToLocalTime()

                };
            }
            else
            {
                return null;
            }
        }

        internal static Dal.Country Convert(this Country source, Dal.Context context)
        {
            return ConvertItem(source, context);
        }

        internal static Dal.Country ConvertItem(Country source, Dal.Context context)
        {
            Dal.Country dataItem = null;
            if (source.Id > 0)
            {
                dataItem = context.Countries.Where(x => x.Id == source.Id).Single();
            }
            else
            {
                dataItem = new CarbonExchange.Dal.Country();
                context.Countries.InsertOnSubmit(dataItem);
                dataItem.Created = DateTime.UtcNow;
                dataItem.SiteId = source.SiteId;
            }
            dataItem.Locale = source.Locale;
            dataItem.Conversion = source.Conversion;
            dataItem.Name = source.Name;
            return dataItem;
        }

        internal static void Validate(this IQueryable<Country> source, Exceptions.ValidationException ex, Dal.Context context)
        {
            foreach (Country item in source)
            {
                item.Validate(ex, context);
            }
        }

        internal static void Validate(this Country source, Exceptions.ValidationException ex, Dal.Context context)
        {
            if (string.IsNullOrEmpty(source.Locale))
            {
                ex.Add("Country Locale must be specified");
            }
            if (source.SiteId == 0)
            {
                ex.Add("Site Id must be specified");
            }
        }

    }
}
